﻿/**************************************************************************
*
* Filename:     ShellLinkNative.cs
* Author:       Mattias Sjögren (mattias@mvps.org)
*               http://www.msjogren.net/dotnet/
*
* Description:  Defines the native types used to manipulate shell shortcuts.
*
* Public types: enum SLR_FLAGS
*               enum SLGP_FLAGS
*               struct WIN32_FIND_DATA[A|W]
*               interface IPersistFile
*               interface IShellLink[A|W]
*               class ShellLink
*
*
* Copyright ©2001-2002, Mattias Sjögren
* 
**************************************************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace ENG.EngStartQueueLib.ShellLink.Native
{
    // IShellLink.Resolve fFlags
    [Flags()]
    public enum SLR_FLAGS
    {
      SLR_NO_UI = 0x1,
      SLR_ANY_MATCH = 0x2,
      SLR_UPDATE = 0x4,
      SLR_NOUPDATE = 0x8,
      SLR_NOSEARCH = 0x10,
      SLR_NOTRACK = 0x20,
      SLR_NOLINKINFO = 0x40,
      SLR_INVOKE_MSI = 0x80
    }

    // IShellLink.GetPath fFlags
    [Flags()]
    public enum SLGP_FLAGS
    {
      SLGP_SHORTPATH = 0x1,
      SLGP_UNCPRIORITY = 0x2,
      SLGP_RAWPATH = 0x4
    }

    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct WIN32_FIND_DATAA
    {
      public int dwFileAttributes;
      public System.Runtime.InteropServices.ComTypes.FILETIME ftCreationTime;
      public System.Runtime.InteropServices.ComTypes.FILETIME ftLastAccessTime;
      public System.Runtime.InteropServices.ComTypes.FILETIME ftLastWriteTime;
      public int nFileSizeHigh;
      public int nFileSizeLow;
      public int dwReserved0;
      public int dwReserved1;
      [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)]
      public string cFileName;
      [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
      public string cAlternateFileName;
      private const int MAX_PATH = 260;
    }

    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct WIN32_FIND_DATAW
    {
      public int dwFileAttributes;
      public System.Runtime.InteropServices.ComTypes.FILETIME ftCreationTime;
      public System.Runtime.InteropServices.ComTypes.FILETIME ftLastAccessTime;
      public System.Runtime.InteropServices.ComTypes.FILETIME ftLastWriteTime;
      public int nFileSizeHigh;
      public int nFileSizeLow;
      public int dwReserved0;
      public int dwReserved1;
      [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)]
      public string cFileName;
      [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
      public string cAlternateFileName;
      private const int MAX_PATH = 260;
    }

    [
      ComImport(),
      InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
      Guid("0000010B-0000-0000-C000-000000000046")
    ]
    public interface IPersistFile
    {
      #region Methods inherited from IPersist

      void GetClassID(
        out Guid pClassID);

      #endregion

      [PreserveSig()]
      int IsDirty();

      void Load(
        [MarshalAs(UnmanagedType.LPWStr)] string pszFileName,
        int dwMode);

      void Save(
        [MarshalAs(UnmanagedType.LPWStr)] string pszFileName,
        [MarshalAs(UnmanagedType.Bool)] bool fRemember);

      void SaveCompleted(
        [MarshalAs(UnmanagedType.LPWStr)] string pszFileName);

      void GetCurFile(
        out IntPtr ppszFileName);

    }

    [
      ComImport(),
      InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
      Guid("000214EE-0000-0000-C000-000000000046")
    ]
    public interface IShellLinkA
    {
      void GetPath(
        [Out(), MarshalAs(UnmanagedType.LPStr)] StringBuilder pszFile,
        int cchMaxPath,
        out WIN32_FIND_DATAA pfd,
        SLGP_FLAGS fFlags);

      void GetIDList(
        out IntPtr ppidl);

      void SetIDList(
        IntPtr pidl);

      void GetDescription(
        [Out(), MarshalAs(UnmanagedType.LPStr)] StringBuilder pszName,
        int cchMaxName);

      void SetDescription(
        [MarshalAs(UnmanagedType.LPStr)] string pszName);

      void GetWorkingDirectory(
        [Out(), MarshalAs(UnmanagedType.LPStr)] StringBuilder pszDir,
        int cchMaxPath);

      void SetWorkingDirectory(
        [MarshalAs(UnmanagedType.LPStr)] string pszDir);

      void GetArguments(
        [Out(), MarshalAs(UnmanagedType.LPStr)] StringBuilder pszArgs,
        int cchMaxPath);

      void SetArguments(
        [MarshalAs(UnmanagedType.LPStr)] string pszArgs);

      void GetHotkey(
        out short pwHotkey);

      void SetHotkey(
        short wHotkey);

      void GetShowCmd(
        out int piShowCmd);

      void SetShowCmd(
        int iShowCmd);

      void GetIconLocation(
        [Out(), MarshalAs(UnmanagedType.LPStr)] StringBuilder pszIconPath,
        int cchIconPath,
        out int piIcon);

      void SetIconLocation(
        [MarshalAs(UnmanagedType.LPStr)] string pszIconPath,
        int iIcon);

      void SetRelativePath(
        [MarshalAs(UnmanagedType.LPStr)] string pszPathRel,
        int dwReserved);

      void Resolve(
        IntPtr hwnd,
        SLR_FLAGS fFlags);

      void SetPath(
        [MarshalAs(UnmanagedType.LPStr)] string pszFile);

    }

    [
      ComImport(),
      InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
      Guid("000214F9-0000-0000-C000-000000000046")
    ]
    public interface IShellLinkW
    {
      void GetPath(
        [Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile,
        int cchMaxPath,
        out WIN32_FIND_DATAW pfd,
        SLGP_FLAGS fFlags);

      void GetIDList(
        out IntPtr ppidl);

      void SetIDList(
        IntPtr pidl);

      void GetDescription(
        [Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszName,
        int cchMaxName);

      void SetDescription(
        [MarshalAs(UnmanagedType.LPWStr)] string pszName);

      void GetWorkingDirectory(
        [Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir,
        int cchMaxPath);

      void SetWorkingDirectory(
        [MarshalAs(UnmanagedType.LPWStr)] string pszDir);

      void GetArguments(
        [Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs,
        int cchMaxPath);

      void SetArguments(
        [MarshalAs(UnmanagedType.LPWStr)] string pszArgs);

      void GetHotkey(
        out short pwHotkey);

      void SetHotkey(
        short wHotkey);

      void GetShowCmd(
        out int piShowCmd);

      void SetShowCmd(
        int iShowCmd);

      void GetIconLocation(
        [Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath,
        int cchIconPath,
        out int piIcon);

      void SetIconLocation(
        [MarshalAs(UnmanagedType.LPWStr)] string pszIconPath,
        int iIcon);

      void SetRelativePath(
        [MarshalAs(UnmanagedType.LPWStr)] string pszPathRel,
        int dwReserved);

      void Resolve(
        IntPtr hwnd,
        SLR_FLAGS fFlags);

      void SetPath(
        [MarshalAs(UnmanagedType.LPWStr)] string pszFile);

    }


    [
      ComImport(),
      Guid("00021401-0000-0000-C000-000000000046")
    ]
    public class ShellLink  // : IPersistFile, IShellLinkA, IShellLinkW 
    {
    }
}
